/**
 * @author Andrey Anisimov <hercules@inbox.ru>
 */

import core.util.ArrayList;
import core.effect.AbstractEffect;

class EffectSequence extends AbstractEffect {

    /**
     * @public
     * @param effects {Array} (optional) Array of {AbstractEffect}
     * @constructor
     */
    this.EffectSequence = function (effects) {
        super();
        this.effects = new ArrayList();
        if (effects) {
            for (var i = 0, n = effects.length; i < n; ++i) {
                this.add(effects[i]);
            }
        }
    };

    /**
     * @public
     * @param looping {Boolean} Whether to looping effects.
     */
    this.setLooping = function (looping) {
        this.looping = looping;
    };

    /**
     * Adds a new effect to the compound effect.
     *
     * @param effect {AbstractEffect} The effect to add.
     */
    this.add = function (effect) {
        effect.addEffectListener(this);
        this.effects.add(effect);
    };

    /**
     * Returns the effect by its index.
     *
     * @return AbstractEffect
     */
    this.get = function (i) {
        return this.effects.get(i);
    };

    /**
     * Checks whether the compound effect is playing.
     *
     * @return Boolean
     */
    this.isPlaying = function () {
        for (var i = this.effects.iterator(); i.hasNext();) {
            if (i.next().isPlaying()) {
                return true;
            }
        }
        return false;
    };

    /**
     * Plays the compound effect.
     */
    this.play = function () {
        this.fireStarted();
        this.iterator = this.effects.iterator();
        this.iterator.next().play();
    };

    /**
     * Stops the compound effect playing.
     */
    this.stop = function () {
        var current = this.currentEffect;
        if (current && current.isPlaying()) {
            current.stop();
        }
    };

    /**
     * Calls when one of the effects in sequence has finished.
     */
    this.onEffectFinished = function () {
        if (this.iterator.hasNext()) {
            this.iterator.next().play();
        } else {
            if (this.looping) {
                this.iterator = this.effects.iterator();
                this.iterator.next().play();
            } else {
                this.fireFinished();
            }
        }
    };

    /**
     * @public
     */
    this.onEffectStarted = function (e) {
        this.currentEffect = e;
    };

    /**
     * Calls when the current effect in sequence has stopped.
     */
    this.onEffectStopped = function () {
        this.fireStopped();
    };

    /**
     * Calls when the current effect in sequence has paused.
     */
    this.onEffectPaused = function () {
        this.firePaused();
    };

    /**
     * Calls when the current effect in sequence has resumed after pause.
     */
    this.onEffectResumed = function () {
        this.fireResumed();
    };
}
